/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.chl.hajo.wss;

import edu.chl.hajo.shop.core.IProductCatalogue;
import edu.chl.hajo.shop.core.Product;
import edu.chl.hajo.shop.core.ProductCatalogue;
import java.net.URI;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.PUT;
import javax.ws.rs.POST;
import javax.ws.rs.GET;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

/**
 *
 * @author tor
 */
@Path("/products")
public class ProductCatalougeResource {

    private IProductCatalogue cat;

    @Context
    private UriInfo uriinfo;
    
    // Must have for JAXB, crashew with protected constructor
    public ProductCatalougeResource() {
        this.cat = Shop.INSTANCE.getProductCatalogue();
    }

    protected ProductCatalougeResource(ProductCatalogue cat) {
        this.cat = cat;
    }

    @GET
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response getAll() {
        List<Product> p = this.cat.getRange(0, this.cat.getCount());
        List<ProductProxy> ppx = new LinkedList<ProductProxy>();
        for (Product product : p) {
            ppx.add(new ProductProxy(product));
        }

        GenericEntity<List<ProductProxy>> ge = new GenericEntity<List<ProductProxy>>(ppx) {
        };

        return Response.ok(ge).build();
    }

    /**
     * Add new product to database
     * @param name the name of the product (string)
     * @param price th eproce of the product (long)
     * @return uri of the created product
     */
    @POST
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response add(@FormParam("name") String name, @FormParam("price") Double price) {
        Response response = null;
        try {
            Product p = new Product(name, price);
            cat.add(p);
            ProductProxy px = new ProductProxy(p);
            URI uri = uriinfo.getAbsolutePathBuilder().path(String.valueOf(p.getId())).build();
            response = Response.ok(uri).build();

        } catch (Exception e) {
            Logger.getLogger(ProductCatalougeResource.class.getName()).log(Level.INFO, "messagess");
            response = Response.serverError().build();
        }

        return response;
    }

    /**
     * Delete an existing product from the database
     * @param id the ID of the product to delete
     * @return ok
     */
    @DELETE
    @Path("{id}")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response remove(@PathParam("id") Long id) {
        this.cat.remove(id);
        return Response.ok().build();
    }

    @PUT
    //@Path("{id}")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response update(@FormParam("id") Long id, @FormParam("name") String name, @FormParam("price") Double price) {
        Response response = null;
        try {
            Product p = new Product(id, name, price);
            this.cat.update(p);
            response = Response.ok(new ProductProxy(p)).build();

        } catch (Exception e) {
            response = Response.serverError().build();
        }

        return response;
    }

    @GET
    @Path("{id}")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response find(@PathParam("id") Long id) {
        Response response = null;
        try {
            response = Response.ok(new ProductProxy(this.cat.find(id))).build();
            
        } catch (Exception e) {
            response = Response.noContent().build();
        }

        return response;
    }

    @GET
    @Path("/query")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response getRange(@QueryParam("first") int first, @QueryParam("nitems") int nitems) {
        Response response = null;
        try { 
            List<Product> pl = this.cat.getRange(first, nitems);
            List<ProductProxy> ppx = new LinkedList<ProductProxy>();
            for (Product product : pl) {
                ppx.add(new ProductProxy(product));
            }

            GenericEntity<List<ProductProxy>> ge = new GenericEntity<List<ProductProxy>>(ppx) {
            };
            
            response = Response.ok(ge).build();

        } catch (Exception e) {
            response = Response.serverError().build();
        }
        return response;
    }

    
    @GET
    @Path("/count")
    @Produces({MediaType.APPLICATION_JSON})
    public Response getCount() {
        PrimitiveJSONWrapper<Integer> px = new PrimitiveJSONWrapper<Integer>(Integer.valueOf(this.cat.getCount()));
        return Response.ok(px).build();
    }
}
